package cn.net.wanji.utils;

import cn.hutool.core.date.DateUtil;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author weining
 * @version 1.0
 * @date 2023-09-13 15:14
 */
public class TimeUtils {

    public static boolean isValidDateTimeFormat(String dateTimeString, String formatPattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatPattern);
        sdf.setLenient(false); // 禁用宽松模式，强制要求精确匹配

        try {
            Date parsedDate = sdf.parse(dateTimeString);
            // 如果解析成功，说明符合指定格式
            return parsedDate != null;
        } catch (ParseException e) {
            // 解析失败，说明不符合指定格式
            return false;
        }
    }

    public static long dateTimeStringToTimestamp(String dateTimeString, String formatPattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatPattern);
        sdf.setLenient(false); // 禁用宽松模式，强制要求精确匹配

        try {
            Date date = sdf.parse(dateTimeString);
            // 将日期对象转换为毫秒级时间戳
            return date.getTime();
        } catch (ParseException e) {
            // 解析失败，返回-1或抛出异常，根据需求处理
            e.printStackTrace();
            return -1;
        }
    }

    public static List<Long> generateUniqueTimestamps(long startTime, long endTime, int n) {
        List<Long> uniqueTimestamps = new ArrayList<>();
        Random random = new Random();

        if (n > (endTime - startTime + 1)) {
            throw new IllegalArgumentException("要生成的不重复时间戳数量大于时间范围内的可能性。");
        }

        for (int i = 0; i < n; i++) {
            long timestamp;
            do {
                // 生成一个随机时间戳，范围在startTime和endTime之间
                timestamp = startTime + random.nextLong() % (endTime - startTime + 1);
            } while (uniqueTimestamps.contains(timestamp)); // 确保时间戳不重复

            uniqueTimestamps.add(timestamp);
        }

        uniqueTimestamps.sort(Long::compareTo); // 对时间戳列表进行排序
        return uniqueTimestamps;
    }

    public static String convertDateTimeString(String inputDateTimeString, String outputFormat) {
        SimpleDateFormat inputSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        SimpleDateFormat outputSdf = new SimpleDateFormat(outputFormat);

        try {
            Date date = inputSdf.parse(inputDateTimeString);
            return outputSdf.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return null; // 处理解析异常
        }
    }

    public static String convertTimeStampFormat(Date currentDate, String formatPattern) {
        SimpleDateFormat outputDateFormat = new SimpleDateFormat(formatPattern);
        return outputDateFormat.format(currentDate);
    }

    public static String convertToISO8601(long milliseconds) {
        Instant instant = Instant.ofEpochMilli(milliseconds);
        ZoneId zoneId = ZoneId.of("UTC"); // 指定时区，可以根据需要修改
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")
                .withZone(zoneId);
        return formatter.format(instant);
    }

    public static SimpleDateFormat getSimpleDateFormatType(String timeString) {
        // 正则表达式匹配模式
        String[] patterns = {
                "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}$",  // "yyyy-MM-dd'T'HH:mm:ss.SSS"
                "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{2}$",  // "yyyy-MM-dd'T'HH:mm:ss.SS"
                "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{1}$",  // "yyyy-MM-dd'T'HH:mm:ss.S"
                "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",           // "yyyy-MM-dd'T'HH:mm:ss"
                "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
                "^\\d{10}$"                                              // "yyyyMMddHH"
        };

        String[] formatNames = {
                "yyyy-MM-dd'T'HH:mm:ss.SSS",
                "yyyy-MM-dd'T'HH:mm:ss.SS",
                "yyyy-MM-dd'T'HH:mm:ss.S",
                "yyyy-MM-dd'T'HH:mm:ss",
                "yyyy-MM-dd HH:mm:ss",
                "yyyyMMddHH"
        };

        for (int i = 0; i < patterns.length; i++) {
            Pattern pattern = Pattern.compile(patterns[i]);
            Matcher matcher = pattern.matcher(timeString);
            if (matcher.matches()) {
                return new SimpleDateFormat(formatNames[i]);
            }
        }
        return null;
    }

    public static String getDateFormatType(String timeString) {
        // 正则表达式匹配模式
        String[] patterns = {
                "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}$",  // "yyyy-MM-dd'T'HH:mm:ss.SSS"
                "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{2}$",  // "yyyy-MM-dd'T'HH:mm:ss.SS"
                "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{1}$",  // "yyyy-MM-dd'T'HH:mm:ss.S"
                "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",           // "yyyy-MM-dd'T'HH:mm:ss"
                "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
                "^\\d{10}$"                                              // "yyyyMMddHH"
        };

        String[] formatNames = {
                "yyyy-MM-dd'T'HH:mm:ss.SSS",
                "yyyy-MM-dd'T'HH:mm:ss.SS",
                "yyyy-MM-dd'T'HH:mm:ss.S",
                "yyyy-MM-dd'T'HH:mm:ss",
                "yyyy-MM-dd HH:mm:ss",
                "yyyyMMddHH"
        };

        for (int i = 0; i < patterns.length; i++) {
            Pattern pattern = Pattern.compile(patterns[i]);
            Matcher matcher = pattern.matcher(timeString);
            if (matcher.matches()) {
                return formatNames[i];
            }
        }
        return null;
    }

    // 比较两个时间差值是否大于指定小时
    public static boolean compareHourTime(String timestamp1, String timestamp2, Integer hour) {
        String format1 = "yyyy-MM-dd HH:mm:ss.SS";
        String format2 = "yyyy-MM-dd HH:mm:ss.SS";
        String[] patterns = {
                "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}$",  // "yyyy-MM-dd'T'HH:mm:ss.SSS"
                "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{2}$",  // "yyyy-MM-dd'T'HH:mm:ss.SS"
                "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{1}$",  // "yyyy-MM-dd'T'HH:mm:ss.S"
                "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",           // "yyyy-MM-dd'T'HH:mm:ss"
                "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
                "^\\d{10}$"                                              // "yyyyMMddHH"
        };

        String[] formatNames = {
                "yyyy-MM-dd'T'HH:mm:ss.SSS",
                "yyyy-MM-dd'T'HH:mm:ss.SS",
                "yyyy-MM-dd'T'HH:mm:ss.S",
                "yyyy-MM-dd'T'HH:mm:ss",
                "yyyy-MM-dd HH:mm:ss",
                "yyyyMMddHH"
        };
        for (int i = 0; i < patterns.length; i++) {
            Pattern pattern = Pattern.compile(patterns[i]);
            Matcher matcher = pattern.matcher(timestamp1);
            Matcher matcher2 = pattern.matcher(timestamp2);
            if (matcher.matches()) {
                format1 = formatNames[i];
            }
            if (matcher2.matches()) {
                format2 = formatNames[i];
            }
        }
        // 定义日期时间格式
        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern(format1);
        DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern(format2);
        // 将时间戳解析为 LocalDateTime 对象
        LocalDateTime dateTime1 = LocalDateTime.parse(timestamp1, formatter1);
        LocalDateTime dateTime2 = LocalDateTime.parse(timestamp2, formatter2);
        // 计算时间差
        Duration duration = Duration.between(dateTime1, dateTime2).abs();
        // 判断时间差是否大于48小时
        return duration.toHours() > hour;
    }

    // 比较两个时间差值是否小于等于指定秒
    public static boolean compareSecondTime(String timestamp1, String timestamp2, Integer second) {
        String format1 = "yyyy-MM-dd HH:mm:ss.SS";
        String format2 = "yyyy-MM-dd HH:mm:ss.SS";
        String[] patterns = {
                "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}$",  // "yyyy-MM-dd'T'HH:mm:ss.SSS"
                "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{2}$",  // "yyyy-MM-dd'T'HH:mm:ss.SS"
                "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{1}$",  // "yyyy-MM-dd'T'HH:mm:ss.S"
                "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$",           // "yyyy-MM-dd'T'HH:mm:ss"
                "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
                "^\\d{10}$"                                              // "yyyyMMddHH"
        };

        String[] formatNames = {
                "yyyy-MM-dd'T'HH:mm:ss.SSS",
                "yyyy-MM-dd'T'HH:mm:ss.SS",
                "yyyy-MM-dd'T'HH:mm:ss.S",
                "yyyy-MM-dd'T'HH:mm:ss",
                "yyyy-MM-dd HH:mm:ss",
                "yyyyMMddHH"
        };
        for (int i = 0; i < patterns.length; i++) {
            Pattern pattern = Pattern.compile(patterns[i]);
            Matcher matcher = pattern.matcher(timestamp1);
            Matcher matcher2 = pattern.matcher(timestamp2);
            if (matcher.matches()) {
                format1 = formatNames[i];
            }
            if (matcher2.matches()) {
                format2 = formatNames[i];
            }
        }
        // 定义日期时间格式
        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern(format1);
        DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern(format2);
        // 将时间戳解析为 LocalDateTime 对象
        LocalDateTime dateTime1 = LocalDateTime.parse(timestamp1, formatter1);
        LocalDateTime dateTime2 = LocalDateTime.parse(timestamp2, formatter2);
        // 计算时间差
        Duration duration = Duration.between(dateTime1, dateTime2).abs();
        long differenceInSeconds = duration.getSeconds();
        // 判断时间差是否小于等于指定秒
        return differenceInSeconds <= second;
    }

    /**
     * 计算两个时间格式的字符串相差了多少分钟
     *
     * @param dateTimeString1 时间1
     * @param dateTimeString2 时间2
     * @return 相差了多少分钟
     */
    public static long calculateMinutesDifference(String dateTimeString1, String dateTimeString2) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 将时间字符串转换为 LocalDateTime 对象
        LocalDateTime dateTime1 = LocalDateTime.parse(dateTimeString1, formatter);
        LocalDateTime dateTime2 = LocalDateTime.parse(dateTimeString2, formatter);
        // 计算两个时间之间的分钟差值
        return Math.abs(ChronoUnit.MINUTES.between(dateTime1, dateTime2));
    }

    /**
     * 获取当天的24个小时时间
     *
     * @Date: 2023-11-28
     */
    public static List<Date> dateConversion(String date) {
        List<Date> dateList = new ArrayList<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        if (!StringUtils.isEmpty(date)) {
            Date parseStartTime = null;
            try {
                parseStartTime = dateFormat.parse(date);
                dateList.add(parseStartTime);
                for (int i = 1; i < 24; i++) {
                    dateList.add(DateUtil.offsetHour(parseStartTime, i));
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }

        }
        return dateList;
    }

    /**
     * 获取两个日期之间的所有日期
     *
     * @param startDateString 开始日期
     * @param endDateString   结束日期
     * @return 返回数据列表
     */
    public static List<String> getDateRange(String startDateString, String endDateString) {
        LocalDate startDate = LocalDate.parse(startDateString.substring(0, 10), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate endDate = LocalDate.parse(endDateString.substring(0, 10), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        List<String> dateList = new ArrayList<>();
        LocalDate currentDate = startDate;
        while (!currentDate.isAfter(endDate)) {
            dateList.add(currentDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            currentDate = currentDate.plusDays(1);
        }
        return dateList;
    }


    /**
     * 获取所有的按小时的列表
     *
     * @param startDateTimeString 开始时间
     * @param endDateTimeString   结束时间
     * @return 小时结果集
     */
    public static List<String> getAllHoursBetween(String startDateTimeString, String endDateTimeString) {
        LocalDateTime startDateTime = LocalDateTime.parse(startDateTimeString, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime endDateTime = LocalDateTime.parse(endDateTimeString, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        List<String> hoursList = new ArrayList<>();

        LocalDateTime tempDateTime = startDateTime;
        while (tempDateTime.isBefore(endDateTime)) {
            hoursList.add(tempDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH")));
            tempDateTime = tempDateTime.plusHours(1);
        }

        return hoursList;
    }

    public static boolean isTimeDifferenceGreaterThanOneHour(String dateTimeString) {
        // 将字符串转换为 LocalDateTime 对象
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter);

        // 获取当前时间
        LocalDateTime currentTime = LocalDateTime.now();

        // 计算时间差
        Duration duration = Duration.between(dateTime, currentTime);

        // 判断时间差是否超过1小时
        return duration.abs().toHours() >= 1;
    }
    public static void main(String[] args) {
        String startDateString = "2023-12-21 10:10:00";
        String endDateString = "2023-12-25 10:10:00";

        List<String> dateList = getDateRange(startDateString, endDateString);

        // 输出所有日期
        for (String date : dateList) {
            System.out.println(date);
        }
    }

}
